/*
 * PennTreebankStringTreeGenerator.java
 *
 * Created on September 12, 2006, 11:31 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package galronnlp.util;

import java.util.Iterator;

/**
 *
 * @author Dennis N. Mehay
 */
public class PennTreebankStringTreeGenerator extends TreeStringGenerator {
    
    /** Creates a new instance of PennTreebankStringTreeGenerator */
    public PennTreebankStringTreeGenerator() { 
        super();
    }
    
    /** Creates new instance with passed-in preference as to whether
     *  inside probabilities should be displayed.
     *  @param displayProb A flag as to whether inside probabilities should
     *                    be displayed.
     */
    public PennTreebankStringTreeGenerator(boolean displayProb) {
        this.displayProb = displayProb;
    }
    
    public String generateMultilineString(Tree t, int indent) {
        String ret = "", indentPadding = "", paddingIncrement = "  ";
                
        for(int i = 0; i < indent; i++) {
            indentPadding += paddingIncrement;
        }
        
        ret += indentPadding;
        
        /** Generating Lexical trees is easy.*/
        if(t.type() == Tree.LEXICAL) {
            ret += "(" + this.generateNodeString(t) + "\n";
            ret += indentPadding;
            ret += (Symbol)(t.getChildren().get(0)) + "\n";
            ret += indentPadding;
            ret += ")";
            return ret + "\n";
        } else {
            /** ----------------------------------------------------------------
             * Generating Trees as Strings in recursion according to type is more
             * efficient.  We will only use high-power Iterators if we have an n-ary
             * tree (n > 2).
             *  ----------------------------------------------------------------
             */
            
            // finalParen will only be non-empty if this is the root of the tree.
            String finalParen = "";
            /*
             * If this tree is the root this effectively
             * adds another pair of (indented) opening and
             * closing brackets and increments the indentation
             * level (and padding) by one unit each.
             */
            if(t.isRoot()) {
                ret += "(" + "\n";
                finalParen += (indentPadding + ")");
                indentPadding += paddingIncrement;
                indent++;
                ret += indentPadding;
            }
            
            // Generate string for current node.
            ret += "(" + this.generateNodeString(t) + "\n";
            // Now for recursion.
            if(t.type() == Tree.BINARY) {
                ret += this.generateMultilineString((Tree)t.getChildren().get(0), indent + 1);
                ret += this.generateMultilineString((Tree)t.getChildren().get(1), indent + 1);
            } else if(t.type() == Tree.UNARY) {
                ret += this.generateMultilineString((Tree)t.getChildren().get(0), indent + 1);
            } else if(t.type() == Tree.NARY) {
                for(Iterator<Tree> it = t.getChildren().iterator(); it.hasNext(); ) {
                    ret += this.generateMultilineString(it.next(), indent + 1);
                }
                
            } // end else if
            
            ret += indentPadding;
            ret += ")" + "\n";
            ret += finalParen;
            return ret;
        }  // End else
        
    } // End method generateMultilineString
    
    
    public String generateSingleLineString(Tree t) {
        String ret = ""; 
        
        /** Generating Lexical trees is easy.*/
        if(t.type() == Tree.LEXICAL) {
            ret += " (" + this.generateNodeString(t);
            ret += " " + (Symbol)(t.getChildren().get(0));
            ret += ")";
            return ret;
        } else {
            /** ----------------------------------------------------------------
             * Generating Trees as Strings in recursion according to type is more
             * efficient.  We will only use high-power Iterators if we have an n-ary
             * tree (n > 2).
             *  ----------------------------------------------------------------
             */
            
            // finalParen will only be non-empty if this is the root of the tree.
            String finalParen = "";
            /*
             * If this tree is the root this effectively
             * adds another pair of opening and
             * closing brackets.
             */
            if(t.isRoot()) {
                ret += "(";
                finalParen += ")";
            }
            
            // Generate string for current node.
            ret += " (" + this.generateNodeString(t);
            
            // Now for recursion.
            if(t.type() == Tree.BINARY) {
                ret += this.generateSingleLineString((Tree)t.getChildren().get(0));
                ret += this.generateSingleLineString((Tree)t.getChildren().get(1));
            } else if(t.type() == Tree.UNARY) {
                ret += this.generateSingleLineString((Tree)t.getChildren().get(0));
            } else if(t.type() == Tree.NARY) {
                for(Iterator<Tree> it = t.getChildren().iterator(); it.hasNext(); ) {
                    ret += this.generateSingleLineString(it.next());
                }
                
            } // end else if
            
            ret += ")";
            ret += finalParen;
            return ret;
        }  // End else
    }
    
}
